Skip to content

Scroll into view after layout settles#292

Open
michael wants to merge 5 commits into
mainfrom
scroll-into-view-after-layout-settles
Open

Scroll into view after layout settles#292
michael wants to merge 5 commits into
mainfrom
scroll-into-view-after-layout-settles

Conversation

@michael

@michael michael commented May 22, 2026

Copy link
Copy Markdown
Owner

Just an experimental alternative to #291

No idea yet, which "layout_has_settled" check is the best one.

Needs testing/evaluation.

@vercel

vercel Bot commented May 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
svedit Ready Ready Preview, Comment May 22, 2026 6:44pm

johannesmutter added a commit that referenced this pull request May 26, 2026
A single deferred scroll computed against an un-settled layout strands
the cursor when images / nested mounts continue reflowing after the
triggering action — the "still found cases where the active node
selection isn't revealed" case on #291.

Node selection (__scroll_node_cursor_into_view):
- IntersectionObserver on the two nodes flanking the cursor gap re-fires
  the scroll on each viewport-edge crossing, until the selection moves
  on, the user scrolls (after a 500ms grace so the settling relayout
  and any inertial scroll can't abort it), or a 2s safety timeout fires.
  Replaces the rAF-poll-until-deadline loop with an event-driven watch
  that catches relayout shifts past the first visibility-pass.

Property and text selection:
- setTimeout(fn, 0) -> await tick() then a rAF (with 50ms fallback for
  background-tab rAF throttling). tick() drains Svelte's effect queue
  so the scroll measures the post-flush DOM, not the pre-flush one.
- Job-id cancellation so a fresh render invalidates an older pending
  scroll instead of letting both yank the viewport.
- Text selection captures focusNode.parentElement at run time, not at
  enqueue time, so a focus that moves during the settle window doesn't
  scroll a stale element.

Node-cursor watch starts also bump the property/text job-id, so a node
render cancels any pending property/text scroll scheduled just before
it.

Adopts the deferred-scroll helper shape from #292 for the property/text
generalization; #292 can be closed in favour of this combined approach.
svedit-lab "Run Smoke Tests": 25/25 pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
johannesmutter added a commit that referenced this pull request May 28, 2026
A single deferred scroll computed against an un-settled layout strands
the cursor when images / nested mounts continue reflowing after the
triggering action — the "still found cases where the active node
selection isn't revealed" case on #291.

Node selection (__scroll_node_cursor_into_view):
- IntersectionObserver on the two nodes flanking the cursor gap re-fires
  the scroll on each viewport-edge crossing, until the selection moves
  on, the user scrolls (after a 500ms grace so the settling relayout
  and any inertial scroll can't abort it), or a 2s safety timeout fires.
  Replaces the rAF-poll-until-deadline loop with an event-driven watch
  that catches relayout shifts past the first visibility-pass.

Property and text selection:
- setTimeout(fn, 0) -> await tick() then a rAF (with 50ms fallback for
  background-tab rAF throttling). tick() drains Svelte's effect queue
  so the scroll measures the post-flush DOM, not the pre-flush one.
- Job-id cancellation so a fresh render invalidates an older pending
  scroll instead of letting both yank the viewport.
- Text selection captures focusNode.parentElement at run time, not at
  enqueue time, so a focus that moves during the settle window doesn't
  scroll a stale element.

Node-cursor watch starts also bump the property/text job-id, so a node
render cancels any pending property/text scroll scheduled just before
it.

Adopts the deferred-scroll helper shape from #292 for the property/text
generalization; #292 can be closed in favour of this combined approach.
svedit-lab "Run Smoke Tests": 25/25 pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant